#ifndef _GAME_RECORD_MAMANAGER_H_
#define _GAME_RECORD_MAMANAGER_H_

#include "Common.h"
#include "Resource.h"
#include "ResourceManager.h"
#include "Singleton.h"
#include "String.h"
#include "Database/Field.h"
#include "DataManager.h"
#include "CenterBattleLogManager.h"

#include "Threading/Mutex.h"

#define DB_NAME_GAMERECORD			"game_record"
#define DB_NAME_GAMECOUNTINFO		"game_count_info"

class  Database;
class  CharPtr;
class  WSSocketPtr;

typedef struct center_game_record_tag_
{
	uint64 record_id;		//记录ID（主键）
	uint32 group_id;		//服务器组ID
	uint32 server_id;		//服务器ID
	uint32 status;			//状态（1 正常 255 删除）
	uint32 type;			//记录类型（1 麻将 2 棋牌 3 棋类）
	uint32 sub_type;		//记录子类型（麻将类中的XXXX， 棋牌类中的XXX）
	uint32 flag;			//标志
	uint32 game_id;			//游戏ID
	uint32 gz_id;			//分区ID
	uint32 town_id;			//房间ID
	uint32 channel_id;		//牌桌ID
	String start_time;		//牌局开始时间
	uint32 play_time;		//游戏时间
	
	String init_data;		//牌局初始数据
	String step_data;		//牌局流程数据
	String calc_data;		//牌局结算数据
	
	int32 data1;			//整形数据1
	int32 data2;			//整形数据2
	int32 data3;			//整形数据3
	int32 data4;			//整形数据4
	int32 data5;			//整形数据5
	int32 data6;			//整形数据6
	int32 data7;			//整形数据7
	int32 data8;			//整形数据8
	
	uint32 udata1;			//无符号整形数据1
	uint32 udata2;			//无符号整形数据2
	uint32 udata3;			//无符号整形数据3
	uint32 udata4;			//无符号整形数据4
	uint32 udata5;			//无符号整形数据5
	uint32 udata6;			//无符号整形数据6
	uint32 udata7;			//无符号整形数据7
	uint32 udata8;			//无符号整形数据8
	
	int64 bdata1;			//长整形数据1
	int64 bdata2;			//长整形数据2
	int64 bdata3;			//长整形数据3
	int64 bdata4;			//长整形数据4
	uint64 ubdata1;			//无符号长整形数据1
	uint64 ubdata2;			//无符号长整形数据2
	uint64 ubdata3;			//无符号长整形数据3
	uint64 ubdata4;			//无符号长整形数据4
	
	float fdata1;			//浮点数据1
	float fdata2;			//浮点数据2
	float fdata3;			//浮点数据3
	float fdata4;			//浮点数据4
	
	String sdata1;			//字符串数据1
	String sdata2;			//字符串数据2
	String sdata3;			//字符串数据3
	String sdata4;			//字符串数据4
	String sdata5;			//字符串数据5
	String sdata6;			//字符串数据6
	String sdata7;			//字符串数据7
	String sdata8;			//字符串数据8
	
	String user_data;		//用户数据
	String config;			//配置信息
	String info;			//备注信息
	
	String create_time;		//记录创建时间
	
	center_game_record_tag_()
	{
		Init();
	}
	
	void Init()
	{
		record_id = 0;			//记录ID（主键）
		group_id = 0;			//服务器组ID
		server_id = 0;			//服务器ID
		status = 0;				//状态（1 正常 255 删除）
		type = 0;				//记录类型（1 麻将 2 棋牌 3 棋类）
		sub_type = 0;			//记录子类型（麻将类中的XXXX， 棋牌类中的XXX）
		flag = 0;				//标志
		game_id = 0;			//游戏ID
		gz_id = 0;				//分区ID
		town_id = 0;			//房间ID
		channel_id = 0;			//牌桌ID
		start_time = "";		//牌局开始时间
		play_time = 0;			//游戏时间(s)
		
		init_data = "";			//牌局初始数据
		step_data = "";			//牌局流程数据
		calc_data = "";			//牌局结算数据
		
		data1 = 0;				//整形数据1
		data2 = 0;				//整形数据2
		data3 = 0;				//整形数据3
		data4 = 0;				//整形数据4
		data5 = 0;				//整形数据5
		data6 = 0;				//整形数据6
		data7 = 0;				//整形数据7
		data8 = 0;				//整形数据8
		
		udata1 = 0;				//无符号整形数据1
		udata2 = 0;				//无符号整形数据2
		udata3 = 0;				//无符号整形数据3
		udata4 = 0;				//无符号整形数据4
		udata5 = 0;				//无符号整形数据5
		udata6 = 0;				//无符号整形数据6
		udata7 = 0;				//无符号整形数据7
		udata8 = 0;				//无符号整形数据8
		
		bdata1 = 0;				//长整形数据1
		bdata2 = 0;				//长整形数据2
		bdata3 = 0;				//长整形数据3
		bdata4 = 0;				//长整形数据4
		ubdata1 = 0;			//无符号长整形数据1
		ubdata2 = 0;			//无符号长整形数据2
		ubdata3 = 0;			//无符号长整形数据3
		ubdata4 = 0;			//无符号长整形数据4
		
		fdata1 = 0.0f;			//浮点数据1
		fdata2 = 0.0f;			//浮点数据2
		fdata3 = 0.0f;			//浮点数据3
		fdata4 = 0.0f;			//浮点数据4
		
		sdata1 = "";			//字符串数据1
		sdata2 = "";			//字符串数据2
		sdata3 = "";			//字符串数据3
		sdata4 = "";			//字符串数据4
		sdata5 = "";			//字符串数据5
		sdata6 = "";			//字符串数据6
		sdata7 = "";			//字符串数据7
		sdata8 = "";			//字符串数据8
		
		user_data = "";			//用户数据
		config = "";			//配置信息
		info = "";				//备注信息
		
		create_time = "";		//记录创建时间
	}
	
}CenterGameRecord;

struct stCenterGameRecordParma
{
	uint32 type;
	uint32 sub_type;
	
	uint32 game_id;
	uint32 gz_id;
	
	uint32 town_id;
	uint32 channel_id;
	
	String init_data;
	String step_data;
	String calc_data;
	
	String start_time;
	uint32 play_time;
	
	String user_data;
	String config;
	String info;
	
	stCenterGameRecordParma()
	{
		init();
	}
	
	void init()
	{
		type = 0;
		sub_type = 0;
		
		town_id = 0;
		channel_id = 0;
		
		game_id = 0;
		gz_id = 0;
		
		init_data = "";
		step_data = "";
		calc_data = "";
		start_time = "";
		
		play_time = 0;
		user_data = "";
		config = "";
		info = "";
	}
};

// 游戏类型定义
enum enGameType
{
	enGameType_MaJiang = 1,		// 麻将
	enGameType_Poker = 2,		// 扑克
	enGameType_Chess = 3,		// 棋类
};

// 麻将子游戏类型
enum enGameSubTypeMaJiang
{
	enGameSubTypeMaJiang_XueZhan = 1,	//血战
	enGameSubTypeMaJiang_XueLiu = 2,	//血流
	enGameSubTypeMaJiang_GuoBiao = 3,	//国标麻将
	enGameSubTypeMaJiang_ErRen = 4,		//二人麻将
	enGameSubTypeMaJiang_GuangDong = 5,	//广东麻将
	enGameSubTypeMaJiang_WuHan = 6,		//武汉麻将
	enGameSubTypeMaJiang_GuiZhou = 7,	//贵州麻将
};

// 扑克子类型类型
enum enGameSubTypePoker
{
	enGameSubTypePoker_DDZ = 1,			// 斗地主
	enGameSubTypePoker_SJ = 2,			// 升级
	enGameSubTypePoker_SRDDZ = 3,		// 四人斗地主
	enGameSubTypePoker_SHK = 4,			// 双抠
};

// 棋类子类型类型
enum enGameSubTypeChess
{
	enGameSubTypeChess_XiangQi = 1,		// 象棋
	enGameSubTypeChess_JunQi = 2,		// 军旗
	enGameSubTypeChess_FeiXingQi = 3,	// 飞行棋
};

#define WGS_GAMERECORD_MUTEX_NAME gamerecord_mutex
#define WGS_GAMERECORD_MUTEX mutable boost::mutex WGS_GAMERECORD_MUTEX_NAME;
#define WGS_GAMERECORD_LOCK		boost::lock_guard<boost::mutex> wgsCenterGameRecordMutexLock(WGS_GAMERECORD_MUTEX_NAME);

//-------------------------组局信息-----------------------
class  SERVER_DECL CenterGameRecordManager:public Singleton<CenterGameRecordManager>
{
public:
	WGS_GAMERECORD_MUTEX
	/**
	 * @创建时间 2017-03-28
	 * @创建人 Roach
	 * @函数作用 添加一条CenterGameRecord记录
	 * @参数
	 * 	@record	CenterGameRecord
	 */
	bool AddCenterGameRecord(CenterGameRecord & record);
	
	/**
	 * @创建时间 2017-03-28
	 * @创建人 Roach
	 * @函数作用 更新CenterGameRecord数据
	 * @参数
	 * 	@record CenterGameRecord
	 */
	bool UpdateCenterGameRecord(const CenterGameRecord & record);
	
	/**
	 * @创建时间 2017-03-28
	 * @创建人 Roach
	 * @函数作用 更新CenterGameRecord数据
	 * @参数
	 * 	@gr_id	
	 *	@fields	字段键值对,格式：fields["key1"] = 1; fields["key2"] = 2;...
	 */
	bool UpdateCenterGameRecord(Fields * fields, const char * QueryString, ...);
	bool UpdateCenterGameRecord(const uint64 &gr_id, Fields * fields);
	
	/**
	 * @创建时间 2017-03-28
	 * @创建人 Roach
	 * @函数作用 根据PD_ID获取一条PD数据
	 * @参数
	 *  @gr_id 		CenterGameRecord record_id
	 * 	@record		CenterGameRecord对象
	 */
	bool GetCenterGameRecord(const uint64 &gr_id, CenterGameRecord * record);
	
	/**
	 * @创建时间 2017-03-28
	 * @创建人 Roach
	 * @函数作用 获取记录列表
	 * @参数
	 * 	@lstData	CenterGameRecord对象列表
	 *  @query 		查询语句条件
	 */
	uint32 GetCenterGameRecordList(std::list<CenterGameRecord> * lstData, const char * query,...);
	
	
public:
	
	//========================逻辑操作相关===================================
	// 存取游戏记录数据
	bool CreateCenterGameRecord(stCenterGameRecordParma & record_parma);
	
	//========================逻辑操作相关===================================
};

#define	 sCenterGameRecordMgr		 CenterGameRecordManager::getSingleton()

struct stGameCountInfo
{
	uint32 data_id;		// 数据序列号
	uint32 agent_id;	// 代理商ID
	uint32 status;		// 状态
	uint32 pid;			// 玩家PID
	uint32 type;		// 类型
	
	int32 data1;		// 附加数据1
	int32 data2;		// 附加数据2
	int32 data3;		// 附加数据3
	int32 data4;		// 附加数据4
	int32 data5;		// 附加数据5
	int32 data6;		// 附加数据6
	int32 data7;		// 附加数据7
	int32 data8;		// 附加数据8
	int32 data9;		// 附加数据9
	int32 data10;		// 附加数据10
	int32 data11;		// 附加数据11
	int32 data12;		// 附加数据12
	
	float fdata1;			//浮点数据1
	float fdata2;			//浮点数据2
	float fdata3;			//浮点数据3
	float fdata4;			//浮点数据4
	float fdata5;			//浮点数据5
	float fdata6;			//浮点数据6
	float fdata7;			//浮点数据7
	float fdata8;			//浮点数据8
	
	String sdata1;		// 字符串数据1
	String sdata2;		// 字符串数据2
	String sdata3;		// 字符串数据3
	String sdata4;		// 字符串数据4
	String sdata5;		// 字符串数据5
	String sdata6;		// 字符串数据6
	String sdata7;		// 字符串数据7
	String sdata8;		// 字符串数据8
	
	String create_time;	// 创建时间
	
	stGameCountInfo()
	{
		Init();
	}
	
	void Init()
	{
		data_id = 0;
		agent_id = 0;
		status = 0;
		pid = 0;
		type = 0;
		
		data1 = 0;
		data2 = 0;
		data3 = 0;
		data4 = 0;
		data5 = 0;
		data6 = 0;
		data7 = 0;
		data8 = 0;
		data9 = 0;
		data10 = 0;
		data11 = 0;
		data12 = 0;
		
		fdata1 = 0.0f;
		fdata2 = 0.0f;
		fdata3 = 0.0f;
		fdata4 = 0.0f;
		fdata5 = 0.0f;
		fdata6 = 0.0f;
		fdata7 = 0.0f;
		fdata8 = 0.0f;
		
		sdata1 = "";
		sdata2 = "";
		sdata3 = "";
		sdata4 = "";
		sdata5 = "";
		sdata6 = "";
		sdata7 = "";
		sdata8 = "";
		
		create_time = "";
	}
};

#define WGS_GAMECOUNTINFO_MUTEX_NAME gamecountinfo_mutex
#define WGS_GAMECOUNTINFO_MUTEX mutable boost::mutex WGS_GAMECOUNTINFO_MUTEX_NAME;
#define WGS_GAMECOUNTINFO_LOCK		boost::lock_guard<boost::mutex> wgsCenterGameRecordMutexLock(WGS_GAMECOUNTINFO_MUTEX_NAME);

//-------------------------组局信息-----------------------
class  SERVER_DECL GameCountInfoManager:public Singleton<GameCountInfoManager>
{
public:
	WGS_GAMECOUNTINFO_MUTEX
	// 添加游戏统计信息
	bool AddGameCountInfo(stGameCountInfo & stGCI);
	// 更新游戏统计信息
	bool UpdateGameCountInfo(const stGameCountInfo & stGCI);
	// 获得游戏统计信息
	bool GetGameCountInfo(const uint32 & data_id, stGameCountInfo * stGCI);
	// 获得游戏统计信息列表
	uint32 GetGameCountInfoList(std::list<stGameCountInfo> * lstData, const char * query,...);
	
	// 获得玩家统计信息
	bool GetGameCountInfo(CharPtr & pChr, stGameCountInfo * stGCI);
	// 初始化玩家统计数据
	stGameCountInfo InitGameCountInfo(CharPtr & pChr);
	// 增加游戏局数
	bool AddDDZPlayGameCount(CharPtr & pChr, bool bWin);
	// 增加比赛次数
	bool AddDDZPlayMatchCount(CharPtr & pChr, const uint32 & match_type);
	// 增加比赛分数
	bool AddDDZMatchScore(CharPtr & pChr, const float & score);
	// 增加冠军次数
	bool AddDDZMatchChampionCount(CharPtr & pChr, const uint32 & match_type);
	// 增加获奖次数
	bool AddDDZBountyCount(CharPtr & pChr, const uint32 & match_type);
};

#define	 sGameCountInfoMgr		 GameCountInfoManager::getSingleton()

#endif	//_GAME_RECORD_MAMANAGER_H_
